package dk.simonvogensen.uirecorder.client;

import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasWidgets;

import com.google.gwt.user.client.Timer;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Document;

import com.google.gwt.event.dom.client.ClickEvent;

import java.util.List;
import java.util.ArrayList;

import org.axed.user.client.DOM;

/**
 * @author $LastChangedBy:$ $LastChangedDate:$
 * @version $Revision:$
 */
public class Utils {

    static List<RecordItem> recordedEventList = new ArrayList<RecordItem>();

    public static void addRecordItem(RecordableWidget widget, Element element, ClickEvent event) {
        recordedEventList.add(new RecordItem(widget, element, event));
    }

    public static void emptyRecorded() {
        recordedEventList.clear();
    }

    public static void startRecording() {
        recordConfig = RecordConfig.RECORD;
    }

    public static void stopRecording() {
        recordConfig = RecordConfig.NONE;
    }

    public static void play() {
        final List<RecordItem> playList = new ArrayList<RecordItem>(recordedEventList);
        final Timer t = new Timer() {
            @Override
            public void run() {
                if(playList.isEmpty()) {
                    cancel();
                }
                else {
                    RecordItem recordItem = playList.get(0);
                    recordItem.dispatchEvent();
                    System.out.println("played:"+recordItem.element.getId());
                    playList.remove(0);
                }
            }
        };
        t.scheduleRepeating(1000);
    }

    public enum RecordConfig {NONE, RECORD, PLAY}
    public enum GenerateConfig {NONE, PREFIX_IDS, PREFIX_AND_GENERATE_IDS}

    static RecordConfig recordConfig;
    static GenerateConfig generateConfig;

    public static void setGenerateConfig(GenerateConfig generateConfig) {
        Utils.generateConfig = generateConfig;
    }

    public static String generateId(RecordableWidget widget) {
        String id;
        if(generateConfig == GenerateConfig.NONE) {
            return widget.getElement().getId();
        }
        else if(generateConfig == GenerateConfig.PREFIX_IDS) {
            id = widget.getElement().getId();
        } else {
            id = tidyString(widget.getInputToGeneratedId());
        }

        Widget w = (Widget) widget;
        while (w.getParent() != null) {
            w = w.getParent();
            String prefix = w.getElement().getId();
            if(prefix != null && !"".equals(prefix))
                id = prefix + "_" + id;
        }
        return id;
    }

    public static void addIds(Widget widget) {
        if (widget instanceof HasWidgets) {
            for (Widget w : (Iterable<Widget>) widget) {
                addIds(w);
            }
        } else if (widget instanceof RecordableComposite) {
            addIds(((RecordableComposite) widget).getWidget());
        }
/*
        if (widget instanceof NetlRadioButton) {
            //setting value of radiobox to id because of qtp
            Element span = widget.getElement();
            Element input = DOM.getChild(span, 0);
            String eventName = ((HasEventName) widget).getEventName();
            DOM.setElementAttribute(input, "value", eventName);
        }
*/
        if (widget instanceof RecordableWidget) {
            String id = generateId((RecordableWidget) widget);
            widget.getElement().setId(id);
        }
    }

    public static boolean isLinkedToRootPanel(Widget widget) {
        if (widget == null) return false;
        if (widget instanceof RecordableRootPanel) return true;
        while (widget.getParent() != null) {
            widget = widget.getParent();
            if (widget instanceof RecordableRootPanel) return true;
        }
        return false;
    }

    private static String tidyString(String text) {
        return text.toLowerCase().replace("æ", "ae").replace("ø", "oe").replace("å", "aa").replace(":", "").replace("*", "").replace(" ", "_");
    }

    public static void add(Widget parent, Widget child) {
        if (Utils.isLinkedToRootPanel(parent)) {
            Utils.addIds(child);
        }
    }

    private static class RecordItem {
        private Element element;
        private NativeEvent event;
        private RecordableWidget widget;

        public RecordItem(RecordableWidget widget, Element element, ClickEvent event) {
            this.widget = widget;
            this.element = element;
            NativeEvent ne = event.getNativeEvent();
            this.event = Document.get().createClickEvent(ne.getButton(), ne.getScreenX(), ne.getScreenY(), ne.getClientX(), ne.getClientY(), ne.getCtrlKey(), ne.getAltKey(), ne.getShiftKey(), ne.getMetaKey());
        }

        public void dispatchEvent() {
            final String value = DOM.getStyleAttribute(widget.getElement(), "border");
//            element.setAttribute("style", value+";border:1px red solid;");
            DOM.setStyleAttribute(widget.getElement(), "border", "1px red solid");
            element.dispatchEvent(event);

            final Timer t = new Timer() {
                @Override
                public void run() {
                    DOM.setStyleAttribute(widget.getElement(), "border", value);
                }
            };
            t.schedule(500);
            
//            element.setAttribute("style", value);

//                worktimeButton.getElement().dispatchEvent(Document.get().createClickEvent(0,0,0,0,0,false, false, false, false));
        }
    }
}
